using System;
using System.Collections;
using System.Diagnostics;
using System.Windows.Forms;
using Microsoft.WowAddonStudio.Lua.RuntimeService.WowBench;

namespace Microsoft.WowAddonStudio.Lua.RuntimeService.ToolWindows
{
	/// <summary>
	/// Represents a control that when clicked displays an associated 
	/// ToolStripDropDown from which the user can select a single Command History item.
	/// </summary>
	public sealed class HistoryToolStripButton : ToolStripDropDownButton, IEventProvider
	{
		#region Public Events

		private event EventHandler<HistoryItemSelectedEventArgs> historyItemSelected;

		/// <summary>
		/// Fires when HistoryItem is clicked on the list.
		/// </summary>
		public event EventHandler<HistoryItemSelectedEventArgs> HistoryItemSelected
		{
			add { historyItemSelected += value; }
			remove { historyItemSelected -= value; }
		}

		#endregion

		#region Private Variables

		private int commandCapacity;
		private ICommandHistory commandHistory;
		private bool initialized;

		#endregion

		#region Lifecycle Methods

		/// <summary>
		/// Initializes a new instance of the <see cref="HistoryToolStripButton"/> class.
		/// </summary>
		public HistoryToolStripButton()
			: this(string.Empty)
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="HistoryToolStripButton"/> class.
		/// </summary>
		/// <param name="text"> The text to be displayed on the ToolStripDropDownButton.</param>
		public HistoryToolStripButton(string text) : this(text, 10)
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="HistoryToolStripButton"/> class.
		/// </summary>
		/// <param name="text"> The text to be displayed on the ToolStripDropDownButton.</param>
		/// <param name="capacity">The total number of elements the internal data structure can hold.</param>
		public HistoryToolStripButton(string text, int capacity)
			: base(text)
		{
			commandCapacity = capacity;
			DropDownItemClicked += OnCommandHistoryToolStripButtonDropDownItemClicked;
			ToolTipText = String.Format("Command History...(last {0} command)", capacity);
		}

		#endregion

		#region Public Properties

		/// <summary>
		/// Gets or sets the total number of elements the internal data structure can hold.
		/// </summary>
		public int MaximumHistoryItem
		{
			get { return commandCapacity; }
			set
			{
				commandCapacity = value;
				if (commandCapacity <= 0)
					commandCapacity = 1;
			}
		}

		#endregion

		#region Public Functions


		/// <summary>
		/// Initializes the specified history.
		/// </summary>
		/// <param name="history">The history.</param>
		public void Initialize(ICommandHistory history)
		{
			if (history == null)
				throw new ArgumentNullException("history");

			if (initialized)
				((IEventProvider)commandHistory).UnsubscribeEvents();

			commandHistory = history;
			commandHistory.CommandAdded += OnCommandHistoryCommandAdded;
			initialized = true;
		}

		/// <summary>
		/// Reset history items in control.
		/// </summary>
		public void Reset()
		{
			base.DropDownItems.Clear();
		}

		#endregion

		#region Event Handlers

		/// <summary>
		/// Handles CommandAdded event from CommandHistory object.
		/// </summary>
		/// <param name="sender">The CommandHistory.</param>
		/// <param name="e">The CommandHistoryEventArgs event data.</param>
		private void OnCommandHistoryCommandAdded(object sender, CommandHistoryEventArgs e)
		{
			if (base.DropDownItems.Count > MaximumHistoryItem)
				base.DropDownItems.RemoveAt(0);

			ToolStripDropDownItem dropDownItem = new ToolStripMenuItem(e.Command);
			base.DropDownItems.Add(dropDownItem);
		}

		/// <summary>
		/// Handles DropDownItemClicked event from ToolStripDropDownButton control.
		/// </summary>
		/// <param name="sender">The ToolStripDropDownButton.</param>
		/// <param name="e">The ToolStripItemClickedEventArgs event data.</param>
		private void OnCommandHistoryToolStripButtonDropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
		{
			if (historyItemSelected != null)
				historyItemSelected(this, new HistoryItemSelectedEventArgs(e.ClickedItem.Text));
		}

		#endregion

		#region Overridden Members

		/// <summary>
		/// Detach all listeners from events.
		/// </summary>
		public void UnsubscribeEvents()
		{
			historyItemSelected = null;
		}

		/// <summary>
		/// Gets the collection of items in the System.Windows.Forms.ToolStripDropDown 
		/// that is associated with this System.Windows.Forms.ToolStripDropDownItem.
		/// </summary>
		public new IEnumerable DropDownItems
		{
			get { return base.DropDownItems; }
		}


		/// <summary>
		/// Releases the unmanaged resources used by the <see cref="T:System.Windows.Forms.ToolStripDropDownItem"/> and optionally releases the managed resources.
		/// </summary>
		/// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
		protected override void Dispose(bool disposing)
		{
			try
			{
				UnsubscribeEvents();

				if (commandHistory != null)
					commandHistory.Dispose();
			}
			catch (Exception e)
			{
				Trace.WriteLine(e);
			}
			finally
			{
				base.Dispose(disposing);
			}
		}

		#endregion

	}
}